home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 12581 / 12581.xpi / components_src / trayToolkitGtk2.cpp < prev    next >
C/C++ Source or Header  |  2009-08-10  |  12KB  |  437 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is TrayToolkit
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Nils Maier
  18.  * Portions created by the Initial Developer are Copyright (C) 2008
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *   Nils Maier <MaierMan@web.de>
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK ***** */
  37.  
  38. #include "trayToolkit.h"
  39.  
  40. #include "nsCOMPtr.h"
  41. #include "nsStringAPI.h"
  42. #include "nsServiceManagerUtils.h"
  43.  
  44. #include "nsIDOMWindow.h"
  45. #include "nsIDOMDocument.h"
  46. #include "nsIDOMDocumentView.h"
  47. #include "nsIDOMAbstractView.h"
  48.  
  49. #include "nsIDOMDocumentEvent.h"
  50. #include "nsIDOMEvent.h"
  51. #include "nsIDOMEventTarget.h"
  52. #include "nsIPrivateDOMEvent.h"
  53. #include "nsIDOMMouseEvent.h"
  54.  
  55. #include "nsIWebNavigation.h"
  56.  
  57. #include "nsIDocument.h"
  58. #include "nsIDocShell.h"
  59. #include "nsIDocShellTreeItem.h"
  60. #include "nsIDocShellTreeOwner.h"
  61.  
  62. #include "nsIXULWindow.h"
  63. #include "nsIBaseWindow.h"
  64.  
  65. #include "nsIInterfaceRequestorUtils.h"
  66. #include "nsIObserverService.h"
  67.  
  68.  
  69. namespace {
  70.  
  71.     /**
  72.      * Helper function that will try to get the nsIBaseWindow from an nsIDOMWindow
  73.      */
  74.     static NS_IMETHODIMP TrayServiceImpl_GetBaseWindow(nsIDOMWindow *aWindow, nsIBaseWindow **aBaseWindow)
  75.     {
  76.         NS_ENSURE_ARG_POINTER(aWindow);
  77.         NS_ENSURE_ARG_POINTER(aBaseWindow);
  78.  
  79.         nsresult rv;
  80.  
  81.         nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow, &rv);
  82.         NS_ENSURE_SUCCESS(rv, rv);
  83.  
  84.         nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(webNav, &rv);
  85.         NS_ENSURE_SUCCESS(rv, rv);
  86.  
  87.         nsCOMPtr<nsIDocShellTreeOwner> dsto;
  88.         rv = dsti->GetTreeOwner(getter_AddRefs(dsto));
  89.         NS_ENSURE_SUCCESS(rv, rv);
  90.  
  91.         nsCOMPtr<nsIXULWindow> xulWindow = do_GetInterface(dsto, &rv);
  92.         NS_ENSURE_SUCCESS(rv, rv);
  93.  
  94.         nsCOMPtr<nsIDocShell> docShell;
  95.         rv = xulWindow->GetDocShell(getter_AddRefs(docShell));
  96.         NS_ENSURE_SUCCESS(rv, rv);
  97.  
  98.         nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(docShell, &rv);
  99.         NS_ENSURE_SUCCESS(rv, rv);
  100.  
  101.         *aBaseWindow = baseWindow;
  102.         NS_IF_ADDREF(*aBaseWindow);
  103.         return NS_OK;
  104.     }
  105. }
  106.  
  107. /**
  108.  * Helper class
  109.  * Encapsulates the Windows specific initialization code and message processing
  110.  */
  111. class TrayWindowWrapper {
  112. public:
  113.     TrayWindowWrapper(TrayWindow *window);
  114.     ~TrayWindowWrapper();
  115.  
  116. private:
  117.      // hold raw pointer. Class instances point to TrayWindow anyway and destructed with it.
  118.     TrayWindow* mWindow;
  119. };
  120.  
  121.  
  122. TrayWindowWrapper::TrayWindowWrapper(TrayWindow *aWindow)
  123.     : mWindow(aWindow)
  124. {
  125. }
  126.  
  127. TrayWindowWrapper::~TrayWindowWrapper()
  128. {
  129. }
  130.  
  131. NS_IMPL_ISUPPORTS0(TrayWindow)
  132.  
  133. TrayWindow::TrayWindow(TrayServiceImpl *aService)
  134. : mService(aService), mWrapper(nsnull), mDOMWindow(nsnull)
  135. {
  136. }
  137.  
  138. NS_IMETHODIMP TrayWindow::Destroy()
  139. {
  140.     // Deleting the wrapper will make it destroy any icon as well
  141.     delete mWrapper.forget();
  142.  
  143.     return NS_OK;
  144. }
  145.  
  146. NS_IMETHODIMP TrayWindow::Init(nsIDOMWindow *aWindow)
  147. {
  148.     NS_ENSURE_ARG_POINTER(aWindow);
  149.  
  150.     nsresult rv;
  151.  
  152.     nsCOMPtr<nsIBaseWindow> baseWindow;
  153.     rv = TrayServiceImpl_GetBaseWindow(aWindow, getter_AddRefs(baseWindow));
  154.     NS_ENSURE_SUCCESS(rv, rv);
  155.  
  156.     nativeWindow native = 0;
  157.     rv = baseWindow->GetParentNativeWindow(&native);
  158.     NS_ENSURE_SUCCESS(rv, rv);
  159.     
  160.     // XXX implement
  161.     return NS_OK;
  162. }
  163.  
  164. NS_IMETHODIMP TrayWindow::GetWindow(nsIDOMWindow **aWindow)
  165. {
  166.     NS_ENSURE_ARG_POINTER(aWindow);
  167.     *aWindow = mDOMWindow;
  168.     NS_IF_ADDREF(*aWindow);
  169.  
  170.     return NS_OK;
  171. }
  172.  
  173. NS_IMETHODIMP TrayWindow::DispatchMouseEvent(const nsAString& aEventName, PRUint16 aButton, nsPoint& pt, PRBool aCtrlKey, PRBool aAltKey, PRBool aShiftKey)
  174. {
  175.     nsresult rv;
  176.  
  177.     nsCOMPtr<nsIDOMDocument> domDocument;
  178.     rv = mDOMWindow->GetDocument(getter_AddRefs(domDocument));
  179.     NS_ENSURE_SUCCESS(rv, rv);
  180.  
  181.     nsCOMPtr<nsIDOMDocumentEvent> docEvent(do_QueryInterface(domDocument));
  182.     nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(domDocument));
  183.     NS_ENSURE_TRUE(docEvent && target, NS_ERROR_INVALID_ARG);
  184.  
  185.     nsCOMPtr<nsIDOMDocumentView> docView(do_QueryInterface(domDocument, &rv));
  186.     NS_ENSURE_SUCCESS(rv, rv);
  187.     
  188.     nsCOMPtr<nsIDOMAbstractView> abstractView; 
  189.     rv = docView->GetDefaultView(getter_AddRefs(abstractView));
  190.     NS_ENSURE_SUCCESS(rv, rv);
  191.  
  192.     nsCOMPtr<nsIDOMEvent> event;
  193.     rv = docEvent->CreateEvent(NS_LITERAL_STRING("MouseEvents"), getter_AddRefs(event));
  194.     NS_ENSURE_SUCCESS(rv, rv);
  195.  
  196.     nsCOMPtr<nsIDOMMouseEvent> mouseEvent(do_QueryInterface(event, &rv));
  197.     NS_ENSURE_SUCCESS(rv, rv);
  198.  
  199.     rv = mouseEvent->InitMouseEvent(
  200.         aEventName,
  201.         PR_FALSE,
  202.         PR_TRUE,
  203.         abstractView,
  204.         0,
  205.         pt.x,
  206.         pt.y,
  207.         0,
  208.         0,
  209.         aCtrlKey,
  210.         aAltKey,
  211.         aShiftKey,
  212.         PR_FALSE,
  213.         aButton,
  214.         target
  215.         );
  216.     NS_ENSURE_SUCCESS(rv, rv);
  217.  
  218.     PRBool dummy;
  219.     return target->DispatchEvent(mouseEvent, &dummy);
  220. }
  221.  
  222. NS_IMPL_ISUPPORTS2(TrayServiceImpl, nsIObserver, trayITrayService)
  223.  
  224. TrayServiceImpl::TrayServiceImpl()
  225. {
  226.     // Observe when the app is going down.
  227.     // Else we might not properly clean up
  228.     // And leave some tray icons behind
  229.     nsresult rv;
  230.     nsCOMPtr<nsIObserverService> obs(do_GetService("@mozilla.org/observer-service;1", &rv));
  231.     if (NS_SUCCEEDED(rv)) {
  232.         obs->AddObserver(static_cast<nsIObserver*>(this), "xpcom-shutdown", PR_FALSE);
  233.     }
  234.     
  235. }
  236. TrayServiceImpl::~TrayServiceImpl()
  237. {
  238.     Destroy();
  239. }
  240. void TrayServiceImpl::Destroy()
  241. {
  242.     // Destroy remaining icons
  243.     PRInt32 count = mWindows.Count();
  244.     for (PRInt32 i = count - 1; i > -1; --i) {
  245.         mWindows[i]->Destroy();
  246.         ReleaseTrayWindow(mWindows[i]);
  247.     }
  248.     mWindows.Clear();
  249.     mWatches.Clear();
  250. }
  251.  
  252. NS_IMETHODIMP TrayServiceImpl::Minimize(nsIDOMWindow *aWindow)
  253. {
  254.     NS_ENSURE_ARG_POINTER(aWindow);
  255.     
  256.     nsresult rv;
  257.     nsCOMPtr<TrayWindow> trayWindow;
  258.     rv = FindTrayWindow(aWindow, getter_AddRefs(trayWindow));
  259.     if (NS_SUCCEEDED(rv)) {
  260.         return NS_ERROR_ALREADY_INITIALIZED;
  261.     }
  262.  
  263.     trayWindow = new TrayWindow(this);
  264.     if (trayWindow == nsnull) {
  265.         return NS_ERROR_OUT_OF_MEMORY;
  266.     }
  267.     rv = trayWindow->Init(aWindow);
  268.     NS_ENSURE_SUCCESS(rv, rv);
  269.  
  270.     if (mWindows.AppendObject(trayWindow) == PR_FALSE) {
  271.         return NS_ERROR_FAILURE;
  272.     }
  273.     DispatchTrustedEvent(aWindow, NS_LITERAL_STRING("TrayMinimize"));
  274.     return NS_OK;
  275. }
  276.  
  277. NS_IMETHODIMP TrayServiceImpl::Restore(nsIDOMWindow *aWindow)
  278. {
  279.     NS_ENSURE_ARG_POINTER(aWindow);
  280.  
  281.     nsresult rv;
  282.     nsCOMPtr<TrayWindow> trayWindow;
  283.     rv = FindTrayWindow(aWindow, getter_AddRefs(trayWindow));
  284.     if (NS_FAILED(rv)) {
  285.         return NS_OK;
  286.     }
  287.  
  288.     rv = trayWindow->Destroy();
  289.     NS_ENSURE_SUCCESS(rv, rv);
  290.  
  291.     rv = ReleaseTrayWindow(trayWindow);
  292.     NS_ENSURE_SUCCESS(rv, rv);
  293.  
  294.     DispatchTrustedEvent(aWindow, NS_LITERAL_STRING("TrayRestore"));
  295.  
  296.     return NS_OK;
  297. }
  298.  
  299. NS_IMETHODIMP TrayServiceImpl::RestoreAll()
  300. {
  301.     nsresult rv;
  302.     PRInt32 count = mWindows.Count();
  303.  
  304.     for (PRInt32 i = count - 1; i > -1; --i) {
  305.         nsCOMPtr<nsIDOMWindow> window;
  306.         rv = mWindows[i]->GetWindow(getter_AddRefs(window));
  307.         NS_ENSURE_SUCCESS(rv, rv);
  308.  
  309.         rv = mWindows[i]->Destroy();
  310.         NS_ENSURE_SUCCESS(rv, rv);
  311.  
  312.         rv = ReleaseTrayWindow(mWindows[i]);
  313.         NS_ENSURE_SUCCESS(rv, rv);
  314.  
  315.         DispatchTrustedEvent(window, NS_LITERAL_STRING("TrayRestore"));
  316.     }
  317.     return NS_OK;
  318. }
  319.  
  320. NS_IMETHODIMP TrayServiceImpl::WatchMinimize(nsIDOMWindow *aWindow)
  321. {
  322.     NS_ENSURE_ARG_POINTER(aWindow);
  323.  
  324.     PRInt32 index = mWatches.IndexOf(aWindow);
  325.     if (index != -1) {
  326.         return NS_OK;
  327.     }
  328.  
  329.     nsresult rv;
  330.  
  331.     nsCOMPtr<nsIBaseWindow> baseWindow;
  332.     rv = TrayServiceImpl_GetBaseWindow(aWindow, getter_AddRefs(baseWindow));
  333.     NS_ENSURE_SUCCESS(rv, rv);
  334.  
  335.     nativeWindow native = 0;
  336.     rv = baseWindow->GetParentNativeWindow(&native);
  337.     NS_ENSURE_SUCCESS(rv, rv);
  338.     
  339.     // XXX Implement
  340.     return NS_OK;
  341. }
  342. NS_IMETHODIMP TrayServiceImpl::UnwatchMinimize(nsIDOMWindow *aWindow)
  343. {
  344.     NS_ENSURE_ARG_POINTER(aWindow);
  345.  
  346.     nsresult rv;
  347.  
  348.     mWatches.RemoveObject(aWindow);
  349.  
  350.     nsCOMPtr<nsIBaseWindow> baseWindow;
  351.     rv = TrayServiceImpl_GetBaseWindow(aWindow, getter_AddRefs(baseWindow));
  352.     NS_ENSURE_SUCCESS(rv, rv);
  353.  
  354.     nativeWindow native = 0;
  355.     rv = baseWindow->GetParentNativeWindow(&native);
  356.     NS_ENSURE_SUCCESS(rv, rv);
  357.     
  358.     // XXX implement
  359.     return NS_OK;
  360. }
  361.  
  362. NS_IMETHODIMP TrayServiceImpl::Observe(nsISupports *, const char *aTopic, const PRUnichar *)
  363. {
  364.     if (strcmp(aTopic, "xpcom-shutdown") == 0) {
  365.         Destroy();
  366.  
  367.         nsresult rv;
  368.         nsCOMPtr<nsIObserverService> obs(do_GetService("@mozilla.org/observer-service;1", &rv));
  369.         if (NS_SUCCEEDED(rv)) {
  370.             obs->RemoveObserver(static_cast<nsIObserver*>(this), "xpcom-shutdown");
  371.         }
  372.     }
  373.     return NS_OK;
  374. }
  375.  
  376. NS_IMETHODIMP TrayServiceImpl::ReleaseTrayWindow(TrayWindow *aWindow)
  377. {
  378.     NS_ENSURE_ARG_POINTER(aWindow);
  379.     mWindows.RemoveObject(aWindow);
  380.     return NS_OK;
  381. }
  382.  
  383.  
  384. NS_IMETHODIMP TrayServiceImpl::FindTrayWindow(nsIDOMWindow *aWindow, TrayWindow **aTrayWindow)
  385. {
  386.     NS_ENSURE_ARG_POINTER(aWindow);
  387.     NS_ENSURE_ARG_POINTER(aTrayWindow);
  388.     
  389.     nsresult rv;
  390.     nsCOMPtr<nsIDOMWindow> domWindow;
  391.     PRInt32 count = mWindows.Count();
  392.     
  393.     for (PRInt32 i = 0; i < count; ++i) {
  394.         rv = mWindows[i]->GetWindow(getter_AddRefs(domWindow));
  395.         if (NS_FAILED(rv)) {
  396.             continue;
  397.         }
  398.         if (domWindow == aWindow) {
  399.             *aTrayWindow = mWindows[i];
  400.             NS_IF_ADDREF(*aTrayWindow);
  401.             return NS_OK;
  402.         }
  403.     }
  404.     return NS_ERROR_FAILURE;
  405. }
  406.  
  407. NS_IMETHODIMP TrayServiceImpl::DispatchTrustedEvent(nsIDOMWindow *aWindow, const nsAString& aEventName)
  408. {
  409.     NS_ENSURE_ARG_POINTER(aWindow);
  410.  
  411.     nsresult rv;
  412.  
  413.     nsCOMPtr<nsIDOMDocument> domDocument;
  414.     rv = aWindow->GetDocument(getter_AddRefs(domDocument));
  415.     NS_ENSURE_SUCCESS(rv, rv);
  416.  
  417.     nsCOMPtr<nsIDOMDocumentEvent> docEvent(do_QueryInterface(domDocument));
  418.     nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(domDocument));
  419.     NS_ENSURE_TRUE(docEvent && target, NS_ERROR_INVALID_ARG);
  420.  
  421.     nsCOMPtr<nsIDOMEvent> event;
  422.     rv = docEvent->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
  423.     NS_ENSURE_SUCCESS(rv, rv);
  424.     
  425.     nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event, &rv));
  426.     NS_ENSURE_SUCCESS(rv, rv);
  427.     
  428.     rv = event->InitEvent(aEventName, PR_FALSE, PR_TRUE);
  429.     NS_ENSURE_SUCCESS(rv, rv);
  430.     
  431.     rv = privateEvent->SetTrusted(PR_TRUE);
  432.     NS_ENSURE_SUCCESS(rv, rv);
  433.  
  434.     PRBool dummy;
  435.     return target->DispatchEvent(event, &dummy);
  436. }
  437.